/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package trabalho;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.util.Version;

/**
 *
 * @author Jayme
 */
public class RunQueries {
    private QueryParser parser;
    private IndexaBase baseIndexada;
    private IndexReader reader;
    private IndexSearcher searcher;
    private Query query;
    TopDocs results;
    private static final int DefaultMaxHits = 10;
    private static final String DefaultFileName = "results.out";

    public RunQueries(IndexaBase baseIndexada) {
        this.baseIndexada = baseIndexada;
        parser = new QueryParser(Version.LUCENE_47, "conteudo", new QueryAnalisador());
        
        // Cria o acesso ao índice  
        try {
            reader = DirectoryReader.open(baseIndexada.getIndexDirectory());
        } catch (IOException ex) {
            Logger.getLogger(RunQueries.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        searcher = new IndexSearcher(reader);  

    }
    
    private void Parse(String textoConsulta){
        try {
            
            query = parser.parse(textoConsulta);
            
        } catch (ParseException ex) {
            Logger.getLogger(RunQueries.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void show() throws IOException{
        if (results == null)
            System.out.println("\nNão há resultados a serem exibidos:\n");  
        else{
            System.out.println("\nSearching for: " + query.toString("conteudo"));
            ScoreDoc[] hits = results.scoreDocs;
            System.out.println("\nDocumentos encontrados:\n");
            for (ScoreDoc scoreDoc : hits) {
                Document doc = searcher.doc(scoreDoc.doc);  
                System.out.println(doc.get("identificador")+" - "+doc.get("conteudo")); 
            }
            int numTotalHits = results.totalHits;
            System.out.println(numTotalHits + " total matching documents");
            System.out.println("Total de docs que contem a busca: "+ hits.length);
        }
    }
    
    public void RunOne(String text) throws IOException{
        RunOne(text, DefaultMaxHits);
    }
    
    public void RunOne(String text, int maxHits) throws IOException{         
        if (!text.isEmpty()){
            Parse(text);
            results = searcher.search(query, null, maxHits); 
        }
        else{
            System.out.println("Consulta Vazia");
        }
    }
    
    public void RunAllQueries(ArrayList<MyQuery> myQueries) throws IOException{
        RunAllQueries(myQueries, DefaultMaxHits);
    }
    
    public void RunAllQueries(ArrayList<MyQuery> myQueries, int maxHitsPerQuery) throws IOException{  
                
        File arq = new File(DefaultFileName);  
        FileOutputStream fos = new FileOutputStream(arq);  
        
        String aux;
        System.out.println("\nRodando benchmark:\n");
        for (MyQuery q: myQueries){        
            System.out.println("Executando consulta: "+q.getIdentificador());
            RunOne(q.getQuery(),maxHitsPerQuery);
            ScoreDoc[] hits = results.scoreDocs;
            //Grava o resultato em arquivo   
            for (ScoreDoc scoreDoc : hits) {
                Document doc = searcher.doc(scoreDoc.doc);  
                fos.write((q.getIdentificador() + " " + doc.get("identificador")+"\n").getBytes());   
            }

        }
        fos.close();
    }
}

